#define _GNU_SOURCE
#include <string.h>
#include "config.h"
#include "CommonDB.h"

extern int g_num;
extern char* g_prefix;
extern char* g_db;
extern char* g_sock;
extern int g_over;
extern char* g_key;
extern int g_cdb;
extern int g_sync;

int test_rdb_put_array();
int test_rdb_get_array();
int test_rdb_del_array();
int test_rdb_put();
int test_rdb_get();
int test_rdb_del();
int test_rdb_size();

typedef db_handle rdb;
//#define rdb_open(_f, _s) dba_create(_f, 0, DB_CREATE, 0)
#define rdb_close dba_free
#define rdb_fetch dba_fetch_ex
#define rdb_replace dba_replace
#define rdb_insert dba_insert
#define rdb_delete dba_delete
#define rdb_setopt_reply (void)
#define rdb_size dba_count

rdb* rdb_open(const char* fname, const char* addr)
{
	rdb* db = 0;
	if (g_cdb) {
		char* home = strdupa(fname);
		char* pos = strrchr(home, '/');
		if (pos) {
			pos[0] = 0;
			TRACE("home=%s db=%s\n", home, pos+1);
			db = dba_create(pos+1, home, DB_CREATE, DB_CREATE|DB_INIT_CDB|DB_INIT_MPOOL);
		}
		else{
			TRACE("not open with cdb - db=%s\n", fname);
			return 0;
		}
	}
	else {
		db = dba_create((char*)fname, 0, DB_CREATE, 0);
	}

	if (db) {
		dba_setsync(db, g_sync);
	}
	return db;
}

int test_rdb_put_array()
{
	rdb* db = 0;
	int i = 0;
	char key[512];
	int res;

	db = rdb_open(g_db, g_sock);
	if (!db) {
		TRACE("! rdb open fail - db=%s\n", g_db);
		return 1;
	}
	TRACE("rdb open - db=%s\n", g_db);

	for (i=0; i<g_num; i++) {
		int keylen;

		sprintf(key, "%s%d", g_prefix, i);
		keylen = strlen(key) + 1;
		if (g_over)
			res = rdb_replace(db, key, keylen, key, keylen);
		else
			res = rdb_insert(db, key, keylen, key, keylen);
		if (res != 0) {
			TRACE("! rdb insert fail - %s\n", key);
		}
	}

	rdb_close(db);
	TRACE("rdb close - db=%s\n", g_db);
	return 0;
}

int test_rdb_get_array()
{
	rdb* db = 0;
	int i = 0;
	char key[512];
	int res;

	db = rdb_open(g_db, g_sock);
	if (!db) {
		TRACE("! rdb open fail - db=%s\n", g_db);
		return 1;
	}
	TRACE("rdb open - db=%s\n", g_db);

	for (i=0; i<g_num; i++) {
		char* v;
		int vlen;
		int keylen;

		sprintf(key, "%s%d", g_prefix, i);
		keylen = strlen(key) + 1;
		res = rdb_fetch(db, key, keylen, (void**)&v, &vlen);
		if (res != 0) {
			TRACE("! rdb fetch fail - %s\n", key);
		}
	}

	rdb_close(db);
	TRACE("rdb close - db=%s\n", g_db);
	return 0;
}

int test_rdb_put()
{
	rdb* db = 0;
	int i = 0;
	int res;
	char* key = g_key;
	int keylen;

	db = rdb_open(g_db, g_sock);
	if (!db) {
		TRACE("! rdb open fail - db=%s\n", g_db);
		return 1;
	}
	TRACE("rdb open - db=%s\n", g_db);

	keylen = strlen(key) + 1;
	if (g_over)
		res = rdb_replace(db, key, keylen, key, keylen);
	else
		res = rdb_insert(db, key, keylen, key, keylen);
	if (res != 0) {
		if (g_over)
			TRACE("! rdb replace fail - %s\n", key);
		else
			TRACE("! rdb insert fail - %s\n", key);
	}
	else {
		if (g_over)
			TRACE("replace ok - v=%s len=%d\n", key, keylen);
		else
			TRACE("insert ok - v=%s len=%d\n", key, keylen);
	}

	rdb_close(db);
	TRACE("rdb close - db=%s\n", g_db);
	return 0;
}

int test_rdb_get()
{
	rdb* db = 0;
	int i = 0;
	int res;
	char* key = g_key;
	int keylen = strlen(g_key) + 1;

	db = rdb_open(g_db, g_sock);
	if (!db) {
		TRACE("! rdb open fail - db=%s\n", g_db);
		return 1;
	}
	TRACE("rdb open - db=%s\n", g_db);

	{
		char* v;
		int vlen;

		res = rdb_fetch(db, key, keylen, (void**)&v, &vlen);
		if (res != 0) {
			TRACE("! rdb fetch fail - %s\n", key);
		}
		else {
			TRACE("fetch ok - v=%s len=%d\n", v, vlen);
		}
	}

	rdb_close(db);
	TRACE("rdb close - db=%s\n", g_db);
	return 0;
}

int test_rdb_del_array()
{
	rdb* db = 0;
	int i = 0;
	char key[512];
	int res;

	db = rdb_open(g_db, g_sock);
	if (!db) {
		TRACE("! rdb open fail - db=%s\n", g_db);
		return 1;
	}
	TRACE("rdb open - db=%s\n", g_db);

	for (i=0; i<g_num; i++) {
		int keylen;

		sprintf(key, "%s%d", g_prefix, i);
		keylen = strlen(key) + 1;
		res = rdb_delete(db, key, keylen);
		if (res != 0) {
			TRACE("! rdb del fail - %s\n", key);
		}
	}

	rdb_close(db);
	TRACE("rdb close - db=%s\n", g_db);
	return 0;
}

int test_rdb_del()
{
	rdb* db = 0;
	int i = 0;
	int res;
	char* key = g_key;
	int keylen = strlen(g_key) + 1;

	db = rdb_open(g_db, g_sock);
	if (!db) {
		TRACE("! rdb open fail - db=%s\n", g_db);
		return 1;
	}
	TRACE("rdb open - db=%s\n", g_db);

	{
		res = rdb_delete(db, key, keylen);
		if (res != 0) {
			TRACE("! rdb del fail - %s\n", key);
		}
		else {
			TRACE("rdb del ok\n");
		}
	}

	rdb_close(db);
	TRACE("rdb close - db=%s\n", g_db);
	return 0;
}

int test_rdb_size()
{
	rdb* db = 0;
	int i = 0;
	int res;

	db = rdb_open(g_db, g_sock);
	if (!db) {
		TRACE("! rdb open fail - db=%s\n", g_db);
		return 1;
	}
	TRACE("rdb open - db=%s\n", g_db);

	{
		int len = 0;
		res = rdb_size(db, &len);
		if (res != 0) {
			TRACE("! rdb size fail\n");
		}
		else {
			TRACE("rdb size=%d ok\n", len);
		}
	}

	rdb_close(db);
	TRACE("rdb close - db=%s\n", g_db);
	return 0;
}

